/*
 *   Copyright 2012, Thomas Kerber
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package milk.jpatch.attribs;

import java.util.ArrayList;
import java.util.List;

import milk.jpatch.CPoolMap;
import milk.jpatch.Patch;
import milk.jpatch.code.CodePatch;

import org.apache.bcel.classfile.Attribute;

/**
 * Denotes the patch of a list of attributes.
 * @author Thomas Kerber
 * @version 1.0.1
 */
public class AttributesPatch implements Patch<List<Attribute>>{
    
    private static final long serialVersionUID = -5181570189748175375L;
    
    /**
     * The single AttributePatches this patch consists of.
     */
    private List<AttributePatch> subPatches;
    
    /**
     * Creates.
     * @param patches The list of AttributePatches to use.
     */
    public AttributesPatch(List<AttributePatch> patches){
        this.subPatches = patches;
    }
    
    /**
     * Generates the attributes patch.
     * @param old The old attributes.
     * @param new_ The new attributes.
     * @param map The CPoolMap from new to old.
     * @return The AttributesPatch to get from old to new.
     */
    public static AttributesPatch generate(Attribute[] old, Attribute[] new_,
            CPoolMap map){
        List<AttributePatch> patches = new ArrayList<AttributePatch>();
        
        // Code must be first so that CodePointHooks are updated properly.
        CodePatch.generate(old, new_, patches, map);
        
        AnnotationsPatch.generate(old, new_, patches);
        ExceptionsPatch.generate(old, new_, patches);
        InnerClassesPatch.generate(old, new_, patches);
        ParameterAnnotationsPatch.generate(old, new_, patches);
        
        ReplaceAttributeTypePatch.generate(old, new_, patches, map);
        RemoveAttributeTypePatch.generate(old, new_, patches);
        
        return new AttributesPatch(patches);
    }
    
    /**
     * 
     * @return The attribute patches this patch consists of.
     */
    public List<AttributePatch> getAttributePatches(){
        return subPatches;
    }
    
    @Override
    public List<Attribute> patch(List<Attribute> attributes, CPoolMap map){
        for(AttributePatch p : subPatches)
            attributes = p.patch(attributes, map);
        return attributes;
    }
    
}
